package com.fingard.avatar.website.generator;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.fingard.avatar.website.model.po.BasePo;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;

/**
 * @author 徐一涛
 * @date 2022/4/24
 */
@Slf4j
@Data
@Accessors(chain = true)
public class GeneratorConfig {
    private String packageName;
    private String moduleName;
    private String mapperPackage;
    private String author = "徐一涛";
    private String dataSourceFile;
    private String projectPath = System.getProperty("user.dir");
    private DataSourceConfig dataSourceConfig;
    private StrategyConfig strategyConfig;

    public void generator() {
        new AutoGenerator(dataSourceConfig).
                global(getGlobalConfig()).
                template(getTemplateConfig()).
                packageInfo(getPackageConfig()).
                strategy(strategyConfig).
                execute(new FreemarkerTemplateEngine());
    }

    public GeneratorConfig setDataSourceConfig(String url, String username, String password) {
        dataSourceConfig = new DataSourceConfig.Builder(url, username, password).build();
        return this;
    }
    public String getAuthor() {
        return this.author;
    }

    private GlobalConfig getGlobalConfig() {
        return new GlobalConfig.Builder().
                outputDir(this.projectPath + "//src/main/java").
                author(getAuthor()).
//                enableSwagger().
                disableOpenDir().build();
    }

    public GeneratorConfig setStrategyConfig(List<String> tables, String[] prefixes) {
        strategyConfig = new StrategyConfig.Builder()
                .enableCapitalMode()
                .enableSkipView()
                .disableSqlFilter()
                .addInclude(StrUtil.join(StrUtil.COMMA, tables))
                .addTablePrefix(prefixes)
                .entityBuilder()
                .superClass(BasePo.class)
                .disableSerialVersionUID()
                .enableChainModel()
                .enableLombok()
                .enableRemoveIsPrefix()
                .enableTableFieldAnnotation()
                .versionColumnName("version")
                .versionPropertyName("version")
                .naming(NamingStrategy.underline_to_camel)
                .columnNaming(NamingStrategy.underline_to_camel)
                .addSuperEntityColumns("id", "create_by", "create_time", "update_by", "update_time", "version","is_delete")
                .formatFileName("%sPo")
                .controllerBuilder()
                .enableHyphenStyle()
                .enableRestStyle()
                .formatFileName("%sController")
                .serviceBuilder()
                .superServiceClass(IService.class)
                .superServiceImplClass(ServiceImpl.class)
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImpl")
                .mapperBuilder()
                .superClass(BaseMapper.class)
                .formatMapperFileName("%sMapper")
                .formatXmlFileName("%sMapper")
                .build();
        return this;
    }

    private PackageConfig getPackageConfig() {
        String xmlPath = String.format("%s//src/main/resources/mapper", projectPath);
        return new PackageConfig.Builder().parent(this.packageName).
                moduleName(moduleName).
                entity("model.po").
                mapper("dao").
                pathInfo(Collections.singletonMap(OutputFile.xml, xmlPath)).
                controller("controller").build();
    }

    private TemplateConfig getTemplateConfig() {
        return new TemplateConfig.Builder().entity("/templates/entity.java").
                controller("/templates/controller.java").
                service("/templates/service.java").
                serviceImpl("/templates/serviceImpl.java").
                mapper("/templates/mapper.java").
                xml("/templates/mapper.xml").build();
    }


}
